package vip.xiaonuo.facedoor.modular.memberdevice.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.service.DeviceBaseService;
import vip.xiaonuo.facedoor.modular.memberdevice.constant.MemberDeviceConstant;
import vip.xiaonuo.facedoor.modular.memberdevice.entity.MemberDevice;
import vip.xiaonuo.facedoor.modular.memberdevice.mapper.MemberDeviceMapper;
import vip.xiaonuo.facedoor.modular.memberdevice.param.LockerMemberSaveParam;
import vip.xiaonuo.facedoor.modular.memberdevice.param.MemberAdminSaveParam;
import vip.xiaonuo.facedoor.modular.memberdevice.vo.LockerMemberDeviceVO;
import vip.xiaonuo.facedoor.modular.memberdevice.vo.MemberDeviceVO;
import vip.xiaonuo.facedoor.modular.memberdevice.service.MemberDeviceService;
import vip.xiaonuo.facedoor.modular.memberuser.entity.MemberUser;
import vip.xiaonuo.facedoor.modular.memberuser.service.MemberUserService;
import vip.xiaonuo.facedoor.modular.orgdevice.entity.OrgDevice;
import vip.xiaonuo.facedoor.modular.orgdevice.service.OrgDeviceService;
import vip.xiaonuo.facedoor.rule.*;


import javax.annotation.Resource;
import java.lang.reflect.Member;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 人员设备关系表service接口实现类
 *
 * @author 胡鹏达
 * @date 2022-07-13 09:03:01
 */
@Service
public class MemberDeviceServiceImpl extends ServiceImpl<MemberDeviceMapper, MemberDevice> implements MemberDeviceService {


    public static final Map<Integer, String> staus = new HashMap<Integer, String>() {
        {
            put(1, "新增中");
            put(2, "修改中");
            put(3, "删除中");
            put(4, "新增失败");
            put(5, "修改失败");
            put(6, "删除失败");
        }
    };
    @Resource
    private MemberDeviceMapper memberDeviceMapper;

    @Resource
    private DeviceBaseService deviceBaseService;

    @Resource
    private OrgDeviceService orgDeviceService;

    @Resource
    private MemberUserService userService;


    @Override
    public PageResult<MemberDeviceVO> selectPage(Long orgId, String name, String jobNum, Long deviceId, Long memberId, Integer memberStatus) {
        return new PageResult<>(memberDeviceMapper.selectPage(PageFactory.defaultPage(), orgId, name, jobNum, deviceId, memberId, memberStatus));
    }

    @Override
    public List<LockerMemberDeviceVO> selectLockerMember(Long deviceId) {
        return memberDeviceMapper.selectLockerMember(deviceId);
    }

    @Override
    public void saveLockerMember(LockerMemberSaveParam deviceVO) {
        MemberDevice memberDevice = null;
        MemberUser memberUser = null;
        DeviceBase deviceBase = deviceBaseService.getById(deviceVO.getDeviceId());
        if (ObjectUtil.isNull(deviceBase.getMaxUseNum())) {
            throw new ServiceException(500, "设备未设置最大使用人数！");
        }
        if (ObjectUtil.isNotEmpty(deviceVO.getId())) {
            memberDevice = memberDeviceMapper.selectById(deviceVO.getId());
            memberUser = userService.getById(memberDevice.getMemberId());
            if (memberUser == null) {
                throw new ServiceException(500, "人员不在白名单中！");
            }
        } else {

            memberUser = userService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getJobNum, deviceVO.getMemberJobNum()));
            if (memberUser == null) {
                throw new ServiceException(500, "找不到人员 请检查工号是否正确！");
            }
            memberDevice = memberDeviceMapper.selectOne(new LambdaQueryWrapper<MemberDevice>()
                    .eq(MemberDevice::getDeviceId, deviceBase.getId())
                    .eq(MemberDevice::getMemberId, memberUser.getId()));
            if (memberDevice == null) {
                throw new ServiceException(500, "人员不在白名单中！");
            }
        }
        // 查询不是当前人员的设备
        List<MemberDevice> memberDevices = this.list(new LambdaQueryWrapper<MemberDevice>().eq(MemberDevice::getDeviceId, deviceBase.getId()).ne(MemberDevice::getMemberId, memberUser.getId()));
        List<String> lockDatas = memberDevices.stream().map(MemberDevice::getLockerData).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        Set<String> lockDataSet = new HashSet<>();
        for (String lockData : lockDatas) {
            Collections.addAll(lockDataSet, lockData.split(","));
        }
//        if (deviceVO.getLockerData().split(",").length >= deviceBase.getMaxUseNum()) {
//            throw new ServiceException(500, "设备已经超过单人使用最大数量！");
//        }
        if (!ObjectUtil.equal(memberDevice.getStatus(), 7)) {
            throw new ServiceException(500, "设备上一次操作结果为 " + staus.get(memberDevice.getStatus()) + "  ！");
        }
        if (StringUtils.isNotBlank(deviceVO.getLockerData())) {
            for (String data : deviceVO.getLockerData().split(",")) {
                if (lockDataSet.contains(data)) {
                    throw new ServiceException(500, "格口" + data + "已经被占用请输入其他格口！");
                }
            }
        }
        memberDevice.setLockerData(deviceVO.getLockerData());
        memberDevice.setStatus(2);
        this.updateById(memberDevice);
    }

    @Override
    public void delete(Long id) throws Exception {

        MemberDevice memberDevice = memberDeviceMapper.selectById(id);
        DeviceBase deviceBase = deviceBaseService.getById(memberDevice.getDeviceId());
        if (deviceBase == null) {
            throw new ServiceException(500, "设备不存在!");
        }
        DeviceTypeRuleService.getIMemberDeviceService(deviceBase.getDeviceType()).delete(id);
    }

    @Override
    public void sync(Long id) throws Exception {

        MemberDevice memberDevice = memberDeviceMapper.selectById(id);
        DeviceBase deviceBase = deviceBaseService.getById(memberDevice.getDeviceId());
        if (deviceBase == null) {
            throw new ServiceException(500, "设备不存在!");
        }
        DeviceTypeRuleService.getIMemberDeviceService(deviceBase.getDeviceType()).sync(id);
    }

    @Override
    public void onKeySync() throws Exception {

        List<DeviceBase> list = deviceBaseService.list(new LambdaQueryWrapper<DeviceBase>().eq(DeviceBase::getDeviceState, "1"));
        List<Long> collect = list.stream().map(DeviceBase::getId).collect(Collectors.toList());

        List<MemberDevice> memberDevices = memberDeviceMapper.selectList(new LambdaQueryWrapper<MemberDevice>()
                .in(MemberDevice::getStatus, MemberDeviceConstant.ADD_FAIL, MemberDeviceConstant.DELETE_FAIL, MemberDeviceConstant.UPDATE_FAIL)
                .in(MemberDevice::getDeviceId,collect).like(MemberDevice::getFailReason,"断线"));

        List<MemberDevice> updateDevices = new ArrayList<>();
        for (MemberDevice memberDevice : memberDevices) {
            if (Objects.equals(memberDevice.getStatus(), MemberDeviceConstant.ADD_FAIL)) {
                memberDevice.setStatus(MemberDeviceConstant.ADD);
            } else if (Objects.equals(memberDevice.getStatus(), MemberDeviceConstant.UPDATE_FAIL)) {
                memberDevice.setStatus(MemberDeviceConstant.UPDATE);
            } else {
                memberDevice.setStatus(MemberDeviceConstant.DELETE);
            }
            updateDevices.add(memberDevice);
        }
        this.updateBatchById(updateDevices);
    }

    @Override
    public PageResult<MemberDeviceVO> listAdminUser(Boolean adminUser, Long deviceId) {
        return new PageResult<>(this.memberDeviceMapper.selectAdminUser(PageFactory.defaultPage(), adminUser, deviceId));

    }

    @Override
    public void deviceAdminSave(MemberAdminSaveParam param) {
        Long deviceId = param.getDeviceId();
        // 待保存的管理员
        List<String> userIds = new ArrayList<>();
        if (StringUtils.isNotEmpty(param.getUserIds())) {
            userIds = Arrays.asList(param.getUserIds().split(","));
        }

        // 当前已存在的管理员
        List<MemberDevice> relations = memberDeviceMapper.selectList(new LambdaQueryWrapper<MemberDevice>()
                .eq(MemberDevice::getDeviceId, deviceId)
                .eq(MemberDevice::getLockerAdmin, true));

        List<MemberDevice> toDelete = new ArrayList<>();
        List<MemberDevice> toUpdate = new ArrayList<>();

        List<Long> existIds = new ArrayList<>();
        // 处理待删除的数据,原来是管理员，重新设置后不是管理员的情况
        List<String> finalUserIds = userIds;
        relations.forEach(memberDevice -> {
            existIds.add(memberDevice.getMemberId());
            if (!finalUserIds.contains(memberDevice.getMemberId() + "")) {
                if (Objects.equals(memberDevice.getStatus(), MemberDeviceConstant.SYNC_SUCCESS)) {// 已经同步成功的数据，修改状态为待删除
                    // 判断该人员是不是普通用户
                    if (isCommonUser(memberDevice.getMemberId(), deviceId)) {
                        memberDevice.setStatus(MemberDeviceConstant.UPDATE);
                        memberDevice.setLockerAdmin(false);
                    } else {
                        memberDevice.setStatus(MemberDeviceConstant.DELETE);
                    }
                    toUpdate.add(memberDevice);
                } else {// 还未同步成功的数据，直接删除(这个情况不存在)
                    toDelete.add(memberDevice);
                }
            }
        });

        List<Long> toAdd = new ArrayList<>();
        userIds.forEach(s -> {
            if (!existIds.contains(Long.parseLong(s))) {
                toAdd.add(Long.parseLong(s));
            }
        });

        List<MemberDevice> addList = new ArrayList<>();
        for (Long id : toAdd) {
            MemberDevice memberDevice = memberDeviceMapper.selectOne(new LambdaQueryWrapper<MemberDevice>()
                    .eq(MemberDevice::getDeviceId, deviceId)
                    .eq(MemberDevice::getMemberId, id)
                    .eq(MemberDevice::getLockerAdmin, false));
            if (memberDevice != null) { // 从普通用户升级成管理员
                memberDevice.setStatus(MemberDeviceConstant.UPDATE)
                        .setLockerAdmin(true);
                toUpdate.add(memberDevice);
            } else {// 空降管理员
                addList.add(new MemberDevice()
                        .setDeviceId(deviceId)
                        .setMemberId(id)
                        .setStatus(MemberDeviceConstant.ADD)
                        .setLockerAdmin(true));
            }
        }
        this.saveBatch(addList);
        this.updateBatchById(toUpdate);
        this.removeBatchByIds(toDelete);
    }

    private boolean isCommonUser(Long userId, Long deviceId) {
        MemberUser user = userService.getById(userId);
        if (user == null) {
            return false;
        }
        long count = orgDeviceService.count(new LambdaQueryWrapper<OrgDevice>()
                .eq(OrgDevice::getOrgId, user.getOrgId())
                .eq(OrgDevice::getDeviceId, deviceId));

        return count > 0;
    }


}
